#include <windows.h>

#include "lib.h"
#include "rw2.h"
#include "ccr.h"

ReadersWritersProb2::ReadersWritersProb2()
  :  ReadersWriters()
{
	ccr = new ConditionalCriticalRegion();
	nReaders = nWriters = 0;
	busy = false;
}

ReadersWritersProb2::~ReadersWritersProb2()
{
	delete ccr;
	ccr = (ConditionalCriticalRegion*)0;
}

bool8
ReadersWritersProb2::initOk()
{
	return (bool8)(ccr != 0);
}

bool8
ReadersWritersProb2::beginRead()
{
	ccr->begin();
	ccr->await((bool8(*)(void*))noWriters, this);
	++nReaders;
	ccr->end();
	return true;	// todo: handle failures
}

void
ReadersWritersProb2::endRead()
{
	ccr->begin();
	--nReaders;
	ccr->end();
}

bool8
ReadersWritersProb2::beginWrite()
{
	ccr->begin();
	++nWriters;
	ccr->await((bool8(*)(void*))okToWrite, this);
	busy = true;
	ccr->end();
    m_changeCount++;
    return true;	// todo: handle failures
}

void
ReadersWritersProb2::endWrite()
{
	ccr->begin();
	--nWriters;
	busy = false;
	ccr->end();
}

bool8
ReadersWritersProb2::noWriters(ReadersWritersProb2* This)
{
	return (bool8)(This->nWriters == 0);
}

bool8
ReadersWritersProb2::okToWrite(ReadersWritersProb2* This)
{
	return (bool8)(!This->busy && This->nReaders == 0);
}
